Circuits generally operate in two fundamental frequency modes, synchronous and asynchronous. A synchronous circuit is a digital circuit in which the various circuit components are synchronized by a centrally generated clock signal. In an ideal synchronous circuit, every change in the logical levels of each storage component is simultaneous. These transitions follow the level change of the clock. Ideally, the input to each storage element has reached its final value before the next clock occurs, so the behavior of the whole circuit can be accurately predicted. Practically, some delay ensues with each logical operation, resulting in a maximum speed at which each synchronous system can run. For these circuits to work correctly, a great deal of care is taken in the design of the clock distribution networks. Static timing analysis is often used to determine a useful upper limit on the operating speed.
As a matter of contrast, an asynchronous circuit is a circuit in which the circuit components operate largely autonomously. The circuit components are not governed by a clock circuit or global clock signal, but instead operate based upon signals that indicate completion of previous instructions and operations. These signals are specified by simple data transfer protocols.
It is well known that cyclic structures in both synchronous and asynchronous logic implementations can limit system performance. A cyclic structure may be generally defined as a feedback path including at least one state control element. There are a variety of known techniques to optimize the performance of synchronous and asynchronous logic in the presence of such cyclic structures. In the asynchronous case, optimization is most often carried out using a method known as slack-matching, which operates by inserting additional buffer stages in a cyclic structure to improve its throughput. In the synchronous case, optimization is most often carried out using a method referred to as re-timing or time-borrowing, where state-holding elements like latches or registers are either virtually or physically moved to different locations in the cycle to balance paths and optimize system performance.